package com.eastsunsoft.swordfish.gateway.filter;

import com.eastsunsoft.swordfish.common.ApiConstant;
import com.eastsunsoft.swordfish.common.ResJson;
import com.eastsunsoft.swordfish.gateway.client.GwUserClient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * <h1>AccessFilter</h1>
 * </br>
 *
 * @author donny
 * @date 11/09/2017
 */
@Component
public class AccessFilter extends ZuulFilter {
    private final static Logger LOGGER = LoggerFactory.getLogger(AccessFilter.class);
    private final String tokenHeader = "Authorization";
    private final String swordfishId = "Swordfish";
    private final String bearer = "Bearer ";
    @Autowired
    private ObjectMapper om;

    @Autowired
    @Qualifier("gwUserClient")
    private GwUserClient gwUserClient;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        LOGGER.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        // check header X-Request-ID
        String requestId = request.getHeader("X-Request-ID");
        if (StringUtils.isEmpty(requestId) || !swordfishId.equals(requestId)) {
            return buildRes(ctx, ApiConstant.ERRCODE_ACCESSTOKEN_INVALID_INT, ApiConstant.ERRMSG_INVALID_HEADER);
        }


        String method = request.getMethod();
        String uri = request.getRequestURI().substring(1);
        System.out.println(uri + ": " + method);
//        List<String> paths = Lists.newArrayList(Splitter.on("/").split(uri));
//        String module = paths.get(1) != null ? paths.get(1) : "";
//        String methodName = paths.get(2) != null ? paths.get(2) : "";
//        String needPerm = "ROLE_" + module + "-" + methodName;
//
//        System.out.println("user:" + gwUserClient.user());
//
        // TODO: 白名单 donny
        if (uri.equals("swordfish-ucms/user/token") || uri.startsWith("swordfish-oss")) {
            return null;
        }

        String authToken = request.getHeader(this.tokenHeader);
        System.out.println(authToken);
        if (StringUtils.isEmpty(authToken) || !authToken.startsWith(bearer)) {
            return buildRes(ctx, ApiConstant.ERRCODE_ACCESSTOKEN_INVALID_INT, ApiConstant.ERRMSG_INVALID_HEADER);
        }

        authToken = authToken.substring(bearer.length());
        ResJson auth = gwUserClient.auth(authToken, uri, method);
        System.out.println(auth);
        if (auth.getErrcode() == ApiConstant.CODE_SUCCESS) {
            if (ApiConstant.STRING_TRUE.equals(auth.getBody())) {
                // 有权限
                return null;
            }

            return buildRes(ctx, ApiConstant.ERRCODE_NO_PERMISSION, ApiConstant.ERRMSG_NO_PERMISSION);
        } else {
            // error
            return buildRes(ctx, auth.getErrcode(), auth.getMsg());
        }


//        Map<String, String> roles = new HashMap<>();
//        if (StringUtils.isEmpty(authToken) || !authToken.startsWith("Bearer ")) {
//            // guest
//            roles.put("ROLE_GUEST", "ROLE_GUEST");
//        } else {
//            // 获取角色
//            roles.put("ROLE_ADMIN", "ROLE_ADMIN");
//        }

//        if (!roles.containsKey(needPerm) && !roles.containsKey("ROLE_ADMIN")) {
//            return buildRes(ctx, ApiConstant.ERRCODE_ACCESSTOKEN_INVALID_INT, ApiConstant.ERRMSG_ACCESS_DENY);
//        }

    }

    private Object buildRes(RequestContext ctx, Integer errcode, String msg) {
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(HttpStatus.OK.value());
        ctx.getResponse().setContentType("application/json");
        ResJson resJson = new ResJson();
        resJson.setErrcode(errcode);
        resJson.setMsg(msg);
        try {
            ctx.setResponseBody(om.writeValueAsString(resJson));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e.getMessage());
        }
        return null;
    }
}
